<template>
  <div class="content-container">
    <a-row :gutter="10">
      <a-col :md="8" :sm="24" style="height: 100%">
        <a-card :bordered="true">
          <a-row style="margin-left: 14px">
            <span>{{ application.name }}</span>
          </a-row>
          <!---- author:os_chengtgen -- date:20190827 --  for:切换父子勾选模式 =======------>
          <div class="drawer-bootom-button">
            <a-dropdown-button>
              <a-icon type="plus-circle" />新增
              <template #overlay>
                <a-menu @click="handleAddMenu">
                  <a-menu-item key="1">新增根节点</a-menu-item>
                  <a-menu-item key="2">新增子节点</a-menu-item>
                </a-menu>
              </template>
            </a-dropdown-button>
            <a-button @click="handleUpdateMenu"> <a-icon type="edit" />修改</a-button
            ><a-button @click="handleDeleteMenu"><a-icon type="delete" />删除</a-button>
          </div>
          <!---- author:os_chengtgen -- date:20190827 --  for:切换父子勾选模式 =======------>

          <!-- 树-->
          <a-col :md="8" :sm="24">
            <a-tree
              multiple
              @select="handleSelectMenuTree"
              v-model:selectedKeys="menuTreeSelectedKeys"
              :tree-data="menuTree"
              :checkStrictly="true"
              v-model:expandedKeys="menuTreeExpandedKeys"
              :autoExpandParent="true"
              :loading="menuTreeLoading"
            />
          </a-col>
        </a-card>
      </a-col>
      <a-col :md="16" :sm="24">
        <a-card :bordered="true">
          <span>功能信息</span>
          <div class="drawer-bootom-button">
            <BasicForm @register="registerForm" />
            <div class="anty-form-btn">
              <a-button @click="handleClearApplicationMenu" type="default">重置</a-button>
              <a-button @click="handleSaveApplicationMenu" type="primary">修改并保存</a-button>
              <a-button @click="handleAddApplicationOperation" type="primary">创建操作</a-button>
            </div>
          </div>
        </a-card>
        <a-card :bordered="true">
          <span>操作信息</span>
          <div class="drawer-bootom-button">
            <BasicTable @register="registerTable">
              <template #action="{ record }">
                <TableAction
                  :actions="[
                    {
                      label: '编辑',
                      icon: 'ant-design:edit-outlined',
                      onClick: handleEditOperation.bind(null, record),
                    },
                    {
                      label: '删除',
                      icon: 'ic:outline-delete-outline',
                      onClick: handleDeleteOperation.bind(null, record),
                    },
                  ]"
                />
              </template>
              <template #bodyCell="{ column, record }">
                <template v-if="column.dataIndex === 'requiredStatus'">
                  {{ record.requiredStatus === 1 ? '是' : '否' }}
                </template>
              </template>
            </BasicTable>
          </div>
        </a-card>
      </a-col>
      <application-operation-modal
        :applicationId="application.id"
        :applicationMenuId="selectedMenuTree?.id"
        @register="registerModal"
        @success="loadMenuOperations"
      />
    </a-row>
  </div>
</template>
<script lang="ts" setup>
  import { reactive, ref } from 'vue';
  import { useRoute } from 'vue-router';
  import { cloneDeep } from 'lodash-es';
  import { message, Modal } from 'ant-design-vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
  import ApplicationOperationModal from './components/ApplicationOperationModal.vue';
  import { useModal } from '/@/components/Modal';
  import type { TreeProps } from 'ant-design-vue';
  import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
  import { applicationMenuFormSchema, applicationOperationColumns } from '../application.data';
  import {
    getApplicationById,
    getApplicationMenuTree,
    createApplicationMenu,
    updateApplicationMenu,
    delApplicationMenu,
    getApplicationOperationList,
    deleteApplicationOperation,
  } from '/@/api/application';
  import type { Application, ApplicationMenu } from '/@/api/application/model';

  const defaultApplicationMenu: ApplicationMenu = {
    id: undefined,
    applicationId: null,
    code: '',
    name: '',
    parentId: null,
    icon: '',
    routeUrl: '',
    url: '',
    component: '',
    sort: 0,
    alwaysShow: false,
    route: false,
    hidden: false,
    keepAlive: false,
    leaf: false,
    managerMenu: false,
    description: '',
  };

  const route = useRoute();

  const application = reactive<Application>({
    id: '',
    code: '',
    name: '',
    icon: '',
    description: '',
  });

  const menuTree = ref<TreeProps['treeData']>([]);
  const menuTreeLoading = ref(false);
  const menuTreeSelectedKeys = ref<string[]>([]);
  const menuTreeExpandedKeys = ref<(string | number)[]>([]);
  const selectedMenuTree = ref<Nullable<ApplicationMenu & { key: string }>>(null);
  const menuOperations = ref<Recordable[]>([]);
  let isUpdate = false;

  const [registerForm, { setFieldsValue, validate, updateSchema, clearValidate, resetFields }] = useForm({
    schemas: applicationMenuFormSchema.map((item) => {
      return {
        ...item,
        componentProps: {
          disabled: true,
        },
      };
    }),
    showActionButtonGroup: false,
  });

  const [registerTable, { setTableData }] = useTable({
    columns: applicationOperationColumns,
    bordered: true,
    showIndexColumn: true,
    actionColumn: {
      width: 200,
      title: '操作',
      align: 'center',
      dataIndex: 'action',
      slots: { customRender: 'action' },
    },
  });

  const [registerModal, { openModal }] = useModal();

  const loadMenuOperations = async () => {
    if (selectedMenuTree.value?.id) {
      menuOperations.value = await getApplicationOperationList(selectedMenuTree.value.id);
      setTableData(menuOperations.value);
    }
  };

  const setExpandedKeys = (node: TreeDataItem) => {
    menuTreeExpandedKeys.value.push(node.key);
    node.children?.forEach((item) => setExpandedKeys(item));
  };

  const loadTree = async () => {
    menuTree.value = [];
    menuTreeLoading.value = true;

    const walk = (data: TreeProps['treeData'], callback: (item: TreeDataItem) => void) => {
      data?.forEach((item) => {
        callback(item);
        walk(item.children, callback);
      });
    };

    const resData = await getApplicationMenuTree(route.query.id as string);

    menuTree.value = cloneDeep(resData);
    walk(menuTree.value, (item) => {
      item.key = item.id;
      item.title = item.name;
    });

    menuTree.value?.forEach((item) => setExpandedKeys(item));

    const menuTreeSelectData = cloneDeep(resData);
    walk(menuTreeSelectData, (item) => {
      item.value = item.id;
      item.label = item.name;
      delete item.id;
      delete item.name;
    });
    menuTreeSelectData.unshift({
      value: '0',
      label: '无',
      children: [],
    });

    updateSchema({
      field: 'parentId',
      componentProps: {
        treeData: menuTreeSelectData,
      },
    });
    menuTreeLoading.value = false;
  };

  const loadData = () => {
    defaultApplicationMenu.applicationId = route.query.id as string;
    getApplicationById(route.query.id as string).then((data) => {
      Object.assign(application, data);
    });
    loadTree();
  };

  const handleSelectMenuTree = async (selectedKeys, e) => {
    await updateSchema(
      applicationMenuFormSchema.map((item) => {
        return {
          field: item.field,
          componentProps: {
            disabled: true,
          },
        };
      })
    );
    selectedMenuTree.value = e.node.dataRef;
    menuTreeSelectedKeys.value = [e.node.dataRef.key];
    await setFieldsValue(selectedMenuTree.value);
    await loadMenuOperations();
  };

  const handleAddMenu = async (e) => {
    isUpdate = false;
    if (e.key === '1') {
      const data = cloneDeep(defaultApplicationMenu);
      data.parentId = '0';
      await setFieldsValue(data);
      await updateSchema(
        applicationMenuFormSchema.map((item) => {
          return {
            field: item.field,
            componentProps: {
              disabled: false,
            },
          };
        })
      );
      await clearValidate();
    } else {
      if (menuTreeSelectedKeys.value.length === 0) {
        message.warning('请选择一个资源节点!');
        return;
      }
      const data = cloneDeep(defaultApplicationMenu);
      if (selectedMenuTree.value) {
        data.parentId = selectedMenuTree.value.id;
      }
      await setFieldsValue(data);
      await updateSchema(
        applicationMenuFormSchema.map((item) => {
          return {
            field: item.field,
            componentProps: {
              disabled: false,
            },
          };
        })
      );
      await clearValidate();
    }
  };

  const handleUpdateMenu = async () => {
    isUpdate = true;
    await updateSchema(
      applicationMenuFormSchema.map((item) => {
        return {
          field: item.field,
          componentProps: {
            disabled: false,
          },
        };
      })
    );
  };

  const handleDeleteMenu = async () => {
    if (!menuTreeSelectedKeys.value?.length) {
      message.warning('请选择一条记录！');
      return;
    }

    Modal.confirm({
      title: '确认删除',
      content: `确定要删除所选中的[${selectedMenuTree.value?.name}]资源，以及子节点资源吗?`,
      onOk: async () => {
        await delApplicationMenu(selectedMenuTree.value?.id as string);
        message.success('删除资源信息成功！');
        menuTreeSelectedKeys.value = [];
        selectedMenuTree.value = null;
        loadTree();
      },
    });
  };

  const handleSaveApplicationMenu = async () => {
    let values = await validate();
    if (!isUpdate) {
      await createApplicationMenu({
        ...values,
        applicationId: application.id,
      });
      message.success('保存资源成功!');
      loadTree();
    } else {
      await updateApplicationMenu({
        id: selectedMenuTree.value?.id,
        ...values,
        applicationId: application.id,
      });
      message.success('保存资源成功!');
      loadTree();
    }
  };

  const handleClearApplicationMenu = () => {
    resetFields();
  };

  const handleAddApplicationOperation = () => {
    openModal(true, {
      isUpdate: false,
    });
  };

  const handleEditOperation = (record: Recordable) => {
    openModal(true, {
      record,
      isUpdate: true,
    });
  };

  const handleDeleteOperation = (record: Recordable) => {
    Modal.confirm({
      title: '确认删除',
      content: '确定要删除所选操作资源吗?',
      onOk: async () => {
        await deleteApplicationOperation([record.id]);
        message.success('删除资源操作信息成功！');
        loadMenuOperations();
      },
    });
  };

  loadData();
</script>
<style scoped>
  .content-container {
    padding: 10px;
  }

  .ant-card-body .table-operator {
    margin: 15px;
  }

  .anty-form-btn {
    width: 100%;
    text-align: center;
  }

  .anty-form-btn button {
    margin: 0 5px;
  }

  .anty-node-layout .ant-layout-header {
    padding-right: 0;
  }

  .header {
    padding: 0 8px;
  }

  .header button {
    margin: 0 3px;
  }

  .ant-modal-cust-warp {
    height: 100%;
  }

  .ant-modal-cust-warp .ant-modal-body {
    height: calc(100% - 110px) !important;
    overflow-y: auto;
  }

  .ant-modal-cust-warp .ant-modal-content {
    height: 90% !important;
    overflow-y: hidden;
  }

  #app .desktop {
    height: auto !important;
  }

  /** Button按钮间距 */
  .ant-btn {
    margin-left: 3px;
  }

  .drawer-bootom-button {
    /*position: absolute;*/
    bottom: 0;
    width: 100%;
    border-top: 1px solid #e8e8e8;
    padding: 10px 16px;
    text-align: left;
    left: 0;
    background: #fff;
    border-radius: 0 0 2px 2px;
  }
</style>
